package service

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"react-blog-server/app/dao"
	"react-blog-server/app/dao/model"
	"react-blog-server/app/dao/repository"
	"react-blog-server/common/auth"
	"react-blog-server/common/base"
)

var UserService = new(userService)

type userService struct{}

func (a *userService) GetLoginUserInfo(c *gin.Context) (*auth.UserInfo, error) {
	value, exists := c.Get(base.UserContextKey)
	if !exists {
		return nil, errors.New("未登录，请先登录")
	}
	claims, ok := value.(*auth.CustomClaims)
	if !ok {
		return nil, errors.New("未登录，请先登录")
	}
	return claims.User, nil
}

func (a *userService) Validate(userDto *model.User) error {
	if userDto == nil {
		return errors.New("user is empty")
	}
	if userDto.UserName == "" {
		return errors.New("user name is empty")
	}
	if len(userDto.Password) < base.MinPasswordLength {
		return fmt.Errorf("password length must great than %d", base.MinPasswordLength)
	}
	return nil
}

func (a *userService) Auth(userDto *model.User) (*model.User, error) {
	if userDto == nil || userDto.UserName == "" || userDto.Password == "" {
		return nil, fmt.Errorf("name or password is empty")
	}
	user, err := repository.UserRepo.GetUserByName(userDto.UserName)
	if err != nil {
		return nil, err
	}
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(userDto.Password)); err != nil {
		return nil, err
	}
	return user, nil
}

func (a *userService) GetUserByName(userName string) (*model.User, error) {
	return repository.UserRepo.GetUserByName(userName)
}

func (a *userService) Create(userDto *model.User) error {
	password, err := bcrypt.GenerateFromPassword([]byte(userDto.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	userDto.Password = string(password)
	return dao.DB.Create(&userDto).Error
}
